-
-
Notifications
You must be signed in to change notification settings - Fork 149
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix NimBLEDevice::init() deadlock problem #584
base: release/1.4
Are you sure you want to change the base?
Conversation
When the priority of NimBLEDevice::init() is greater than (tskIDLE_PRIORITY+1), NimBLEDevice::init() will block NimBLE host task and wait for NimBLE host task infinitely
I've never heard of or experienced this issue before, do you have any examples where this can be reproduced? |
Hello @h2zero, Here is the minimum reproducible example (it tested it with bc333cc), #include <NimBLEDevice.h>
void InitNimbleTask(void* args)
{
Serial.println("Initializing NimBLEDevice");
NimBLEDevice::init("NimBLE-Arduino");
Serial.println("Initialized");
NimBLEDevice::startAdvertising();
vTaskDelete(NULL);
}
void setup() {
Serial.begin(115200);
// host_task has priority (configMAX_PRIORITIES - 4)
const uint32_t priority = (configMAX_PRIORITIES - 3);
// host_task is pinned at core 0
xTaskCreatePinnedToCore(InitNimbleTask, "InitNimbleTask", 8192, NULL, priority, NULL, 0);
}
void loop() {
} As stated in the PR, I think it's because
When NimBLEDevice::init() has priority greater than (configMAX_PRIORITIES - 4) , the host_task starves.
And if we set the priority of Some even trickier situation,
|
Due to the nature of the BLE stack I would highly recommend using a task priority for the application that is less than the host task. Is there a specific purpose to have your application run at a higher priority than the host task? |
Actually, I don't really need the priority of application be higher, I just accidentally found this problem when I set different task priority for my application. |
@CW-B-W That is a great explanation, thank you for this. I have tested your example and propose a different fix. Instead of the semaphore, could you just replace the |
Came here to say I've also independently found this issue |
FYI I tried to use |
Doesn't look like the patch works for me either. xSemaphoreTake never returns. |
So after a lot of debugging it looks like one of my own tasks starving resources from NimBLEDevice. From the comments it looks like this lib doesn't need to create it's own task. I'd love to know how to implement this. |
@i-am-shodan you shouldn't need to do anything other that add a call to |
I'm also experiencing crashes due to starvation of the host task. Is there a reason not to merge thechange proposed in #584 (comment) ?? This change looks good to me. |
Unless you have a very good reason to have any tasks with priority higher than the BLE host task then you should make sure that everything else is lower priority.
No reason, just haven't got to it yet 😄 |
Why is it so? Because the BLE stack is full of timers/watchdogs which will
trigger an error if they are not rested on time?
Xavier
Le sam. 21 sept. 2024, 18:05, h2zero ***@***.***> a écrit :
… Unless you have a very good reason to have any tasks with priority higher
than the BLE host task then you should make sure that everything else is
lower priority.
Is there a reason not to merge thechange proposed in #584 (comment)
<#584 (comment)>
?? This change looks good to me.
No reason, just haven't got to it yet 😄
—
Reply to this email directly, view it on GitHub
<#584 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAYCLBKJG43UMO7GOMKQTQDZXWKLZAVCNFSM6AAAAABMCOBIO2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNRVGIZTOMBXGE>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Yes, there is a lot of things going on in the BLE stack and it needs time to process. |
NimBLEDevice::host_task()
has priority(configMAX_PRIORITIES - 4)
, which is defined atNimBLE-Arduino/src/nimble/porting/npl/freertos/src/nimble_port_freertos.c
Lines 60 to 61 in bc333cc
When the priority of
NimBLEDevice::init()
is greater than(configMAX_PRIORITIES - 4)
,NimBLEDevice::init()
will blockNimBLEDevice::host_task()
but still wait forNimBLEDevice::host_task()
infinitely (waiting form_synced
to be set), resulting in the deadlock betweenNimBLEDevice::init()
andNimBLEDevice::host_task()
.This is caused by this while loop
NimBLE-Arduino/src/NimBLEDevice.cpp
Lines 909 to 911 in bc333cc
When the priority of
NimBLEDevice::init()
is greater thanNimBLEDevice::host_task()
, it cannot yield and letNimBLEDevice::host_task()
be executed.Using a binary semaphore can resolve this problem.